use std::{fs::remove_file, time::Duration};

use clap::Parser;
use wtask_base::{error::WResult, export::{Local, Timelike, log_error, log_info, tokio_sleep}, logs::{LogArgs, log_init}, machine::runtime_init, timer::TimerRun};
use wtask_web::{get_file_web_running, web, FlowApp, WEB_SESSION};



#[derive(Debug, Parser)]
#[command(author, version, about="wTask Web客户端，可以从Web连接machine", help_template = "\
{before-help}
{about-with-newline}
{usage-heading} {usage}
{all-args}{after-help}

Version: {version}
Author: {author-with-newline}
")]
struct CMDArgs {
    /// 启动web的端口
    #[arg(long, default_value = "8080")]
    port: u32,

    /// 启动websocket的端口
    #[arg(long, default_value = "8081")]
    wsport: u32,

    /// web webdav端口，
    /// 运行该web服务所在的设备可通过WebDav协议访问
    /// 登录时用户名不要求（可随便填写），密码要求是machine token，可通过本设备运行的其余wTask服务获取machine token
    /// 注意webdav windows挂载要求https
    #[arg(long, default_value = "8079")]
    webwebdav: u32,

    /// machine webdav端口
    /// 将远程的machine变为本地的WebDAV，WebDav登录时用户名是ip:port，密码是token
    /// 注意webdav windows挂载要求https
    #[arg(long, default_value = "5005")]
    machinewebdav: u32,

    #[command(flatten)]
    log_args: LogArgs,
}


fn main() -> WResult<()> {
    let mut args = CMDArgs::parse();
    log_info!("Args: {args:?}");
    args.log_args.noterminal = true;
    log_init(&args.log_args);
    
    let runtime = runtime_init(16)?;
    runtime.spawn(async {
        loop {
            // 保证从0秒左右开始运行任务
            let sec_gap = 60 - Local::now().second();
            tokio_sleep(Duration::from_secs(sec_gap as u64)).await;
            let _ = TimerRun::<FlowApp>::run_all().await;
        }
    });
    runtime.block_on(async move {
        match web(args.port, args.wsport, args.webwebdav, args.machinewebdav).await {
            Ok(_) => {},
            Err(e) => {
                log_error!("web stop, error: {e}");
            }
        }
        let _ = remove_file(get_file_web_running());
    });
    runtime.block_on(async move {
        WEB_SESSION.drop_data().await;
    });
    runtime.shutdown_background();
    Ok(())
}